package 多态性;
/*
*面向兑现特征之三：多态性
*  1. 理解多态性，可以理解为一个事务的多种形态。
*  2. 何为多态性：
*         对象的多态性，父类的引用指向子类的对象(或子类的对象赋给父类的引用)
*  3. 多态的使用，虚拟方法调用
*     有了对象的多态性以后，我们在编译期，只能调用父类中声明的方法，但在运行期，我们实际执行的时子类重写父类的方法。
*    总结：编译，看左边。运行，看右边
* 4. 多态性使用前提 ①要有类的继承关系②要有方法的重写
* 5.对象的多态性，只是用于方法，不适用于属性(编译和运行都看左边)
*
* 1.若子类重写了父类方法，就意味着子类里定义的方法彻底覆盖了父类里的同名方法，
* 系统将不可能把父类里的方法转移到子类中。 运行看右边
* 2. 对于实例变量则不存在这样的现象，即使子类里定义与父类完全相同的实例变量
* 这个实例变量依然不可能覆盖父类中定义的实例变量，编译运行都看左边
* **************************************************************
*
* */
public class PersonTest {
    public static void main(String[] args) {
        Person p1=new Person();
        p1.eat();
        Man man=new Man();
        man.eat();
        man.age=25;
        man.earnMoney();
        //******************************
        //对象的多态性，父类的引用指向子类的对象
        Person p2=new Man();
        //多态的使用；当调用子父类同名同参数的方法时，实际执行的时子类重写父类的方法---虚拟方法调用
        p2.eat();
        p2.walk();
        p2.show();
        System.out.println("*************************");
        //不能调用子类所持有的方法、属性、编译时，p2是Person类型
        //p2.earnMoney();调用失败


        p2.name="Tom";


        //有了对象的多态性以后，内存中实际上是加载了子类特有的属性和方法，但是由于变量声明为父类型，导致
        //编译时，只能调用父类中声明的属性和方法。子类持有的属性和方法不能调用
        //如何才能调用子类持有的书信和方法？
        //向下转型 也叫强制类型转化
        Man m1=(Man)p2;// 强制将person类转化成man类
        m1.isSmoking=true;
        //使用强制时，可能出现ClassCastException的异常
//        Woman w1=(Woman)p2;
//        w1.goShopping();

/*
* instanceof关键字的使用
*
* a instanceof A ：判断对象a 是否是类A的实例。如果是，返回true， 如果不是，返回false
* 使用情景，为了避免在向下转型是出现CLassCastException的异常，我们在向下转型之前，先进行instanceof的
* 判断，一旦返回true，就进行向下转型，如果返回false，不进行向下转型。
* 如果a instanceof A 返回true，则a instanceof B也返回true
* 其中，类B是类A的父类
* */
//        if (p2 instanceof Woman) {
//            Woman w1=(Woman) p2;
//            w1.goShopping();
//            System.out.println("成功运行该");
//        }
        if(p2 instanceof Man){
            Man m2=(Man)p2;
            m2.earnMoney();
        }
        if(p2 instanceof Person){
            System.out.println("这时一个person类");
        }
        Person p3=new Woman();
        Woman m3=(Woman)p3;
        m3.goShopping();
   //练习以
//        编译时通过，运行时不通过
        // 举例一
//        Person p5=new Woman();
//        Man m3=(Man)p5;
//        m3.earnMoney();
//       举例二
//        Person p4=new Person();
//        Man m4=(Man)p4;
//        m4.earnMoney();

    }
}
